package com.lijinquan.springcloud.controller;

import cn.lijinquan.p2p.entites.*;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.lijinquan.springcloud.service.*;
import com.lijinquan.springcloud.utils.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.util.*;

/**
 * Created by lijinquan on 2019/10/6.
 */
@RestController
@Transactional
public class ChargesController {

    private final Logger logger = LoggerFactory.getLogger(getClass());
    @Autowired
    private RedisService redisService;
    @Autowired
    private ProductService productService;
    @Autowired
    private UserAcountService userAcountService;
    @Autowired
    private WeigthRuleService weigthRuleService;
    @Autowired
    private ProductAccountService productAccountService;
    @Autowired
    private FundingNotMatchedService fundingNotMatchedService;
    @Autowired
    private AccountLogService accountLogsService;

    @Autowired
    private ExpectedReturnService expectedReturnService;

    @RequestMapping(value = "/charges/addMayTake", method = RequestMethod.POST)
    public Boolean addMayTake(@RequestBody ProductAccount productAccount) {
        ResultMap<Boolean> rm = new ResultMap<>();
        Integer pProductId = productAccount.getpProductId();// 理财产品id
        BigDecimal pAmount = productAccount.getpAmount();// 投资金额
        int pDeadline = productAccount.getpDeadline();// 期限
        Double pExpectedAnnualIncome = productAccount.getpExpectedAnnualIncome();// 年化收益
        Double pMonthInterest = productAccount.getpMonthInterest();// 月赢取利息
        Double pMonthlyExtractInterest = productAccount.getpMonthlyExtractInterest();// 每月提取利息


        UserAcount uaCondition = new UserAcount();
        Integer userId = productAccount.getpUid();

        // 总本息
        String endInvestTotalMoney = BigDecimalUtil.endInvestTotalMoney(pAmount.toString(), pDeadline + "", pExpectedAnnualIncome.toString(),
                pMonthlyExtractInterest.toString());

        // 本次待收利息 =总本息-投资金额
        BigDecimal mayInterrestIncome = BigDecimalUtil.sub(endInvestTotalMoney.toString(), pAmount.toString());

        // 3.封装用户帐户表信息
        // 先查询用户帐户表数据
        uaCondition.setUserId(userId);
        UserAcount userAccount = userAcountService.findUserAcountByUserId(uaCondition);
        // a. 修改帐户中的余额 现余额=原余额-投资金额
        BigDecimal _balance = BigDecimalUtil.sub(userAccount.getBalance().doubleValue(), pAmount.doubleValue());
        // b. 总计待收本金 =原总计待收本金+投资金额
        BigDecimal _inverstmentW = BigDecimalUtil.add(userAccount.getInverstmentW() != null ? userAccount.getInverstmentW().doubleValue() : 0, pAmount.doubleValue());
        // c. 总计待收利息 =原总计待收利息+本次待收利息
        BigDecimal _interestTotal = BigDecimalUtil.add(userAccount.getInterestTotal() != null ? userAccount.getInterestTotal().doubleValue() : 0,
                mayInterrestIncome.doubleValue());
        // d. 月取计划投资总额 原月取总额+投资金额
        BigDecimal _recyclingInterest = BigDecimalUtil.add(userAccount.getRecyclingInterest() != null ? userAccount.getRecyclingInterest().doubleValue() : 0,
                pAmount.doubleValue());
        // e. 已投资总额 原投资总额+投资金额
        BigDecimal _inverstmentA = BigDecimalUtil.add(userAccount.getInverstmentA() != null ? userAccount.getInverstmentA().doubleValue() : 0, pAmount.doubleValue());

        UserAcount uam = new UserAcount();
        uam.setBalance(_balance);
        uam.setInverstmentW(_inverstmentW);
        uam.setInterestTotal(_interestTotal);
        uam.setRecyclingInterest(_recyclingInterest);
        uam.setInverstmentA(_inverstmentA);
        uam.setId(userAccount.getId());

        // 4.ProductAccount表数据封装
        ProductAccount pa = new ProductAccount();

        // 它需要产品信息 ---从请求参数中可以获取产品id,从数据库中查询出产品信息
        Product product = productService.getProductById(Integer.valueOf(pProductId));

        // 1.封装数据到ProductAccount对象
        String userName = productAccount.getUsername();
        pa.setUsername(userName);
        pa.setpUid(userId);
        //关于产品相关信息(产品名称 产品id   产品利率类型)
        pa.setpProductId(product.getId());
        pa.setpProductName(product.getProductName());
        pa.setpEarningsType(product.getEarningType());
        //	关于productAccount自己信息
        // a. 开始时间 ---new Date()
        Date date = new Date();
        pa.setpBeginDate(date);
        // b. 结束时间 ---new Date()+投资期限
        Calendar c = Calendar.getInstance();
        c.add(Calendar.MONTH, pDeadline);
        pa.setpEndDate(c.getTime());
        // c. 投资编号—“TZNO”+随机id它是根据时间生成
        String randomNum = RandomNumberUtil.randomNumber(date);
        pa.setpSerialNo("TZNO" + randomNum);
        // d. 投资金额----请求参数
        pa.setpAmount(pAmount);
        // e. 投资期限---请求参数
        pa.setpDeadline(pDeadline);
        // f. 年化率-----请求参数
        pa.setpExpectedAnnualIncome(pExpectedAnnualIncome);
        // g. 月利息-----请求参数
        pa.setpMonthInterest(pMonthInterest);
        // h. 月提取利息----请求参数
        pa.setpMonthlyExtractInterest(pMonthlyExtractInterest);
        // i. 可用余额-----在用户帐户表中有
        pa.setpAvailableBalance(_balance);
        // j. 到期收回总本金----在用户帐户表中有
        pa.setpEndInvestTotalMoney(_inverstmentW.doubleValue());
        // k. 待匹配状态---从匹配状态工具类中获取 InvestStatus
        pa.setpStatus(InvestStatus.WAIT_TO_MATCH);
        // l. 还有其它项
        pa.setaCurrentPeriod(1);

        // 5.交易流水
        AccountLog accountLog = new AccountLog();
        // 1.需要用户id
        accountLog.setaUserId(userId);
        // 2.主帐户id记录成用户id
        accountLog.setaMainAccountId(userId);
        // 3.需要投资记录的id----就是ProductAccount主键
        // 4.当前期----第一期
        accountLog.setaCurrentPeriod(1);
        // 5.收付-----从工具类中获取InvestTradeType. PAY
        accountLog.setaReceiveOrPay(InvestTradeType.PAY);
        // 6.交易流水号 LSNO+随机id
        accountLog.setaTransferSerialNo("LSNO" + randomNum);
        // 7.交易时间 new Date()
        accountLog.setaDate(date);
        // 8.交易类型 FundsFlowType. INVEST_TYPE
        accountLog.setaType(FundsFlowType.INVEST_TYPE);
        // 9.交易状态 FundsFlowType. INVEST_SUCCESS
        accountLog.setaTransferStatus(FundsFlowType.INVEST_SUCCESS);
        // 10.交易前金额 记录的是交易前的余额
        accountLog.setaBeforeTradingMoney(userAccount.getBalance().doubleValue());
        ;
        // 11.交易金额 投资的金额
        accountLog.setaAmount(pAmount.doubleValue());
        // 12.交易后金额 记录的是交易后的余额
        accountLog.setaAfterTradingMoney(_balance.doubleValue());
        // 13.交易详情 月取操作+投资流水号
        accountLog.setaDescreption("月取计划TZNO" + randomNum);

        // 6.向待匹配资金表中插入数据
        FundingNotMatched fnm = new FundingNotMatched();
        // 1.投资记录id---就是ProductAccount的id
        // 2.待匹配金额----就是投资金额
        fnm.setfNotMatchedMoney(pAmount.doubleValue());
        // 3.资金类型 124 新增投资
        fnm.setfFoundingType(124);
        // 4.投资时间 new Date
        fnm.setfCreateDate(date);
        // 5.权重
        WeigthRule wrcondition = new WeigthRule();
        wrcondition.setWeigthType(124);
        WeigthRule wr = weigthRuleService.findByCondition(wrcondition);
        fnm.setfFoundingWeight(wr.getWeigthValue());
        fnm.setfIsLocked(FundsFlowType.FUND_NOT_LOCK);
        fnm.setUserId(userId);

        // 7.操作
        try {
            //更新用户账户表
            userAcountService.modify(uam);
            //添加用户购买产品记录表
            productAccountService.addProductAccount(pa);
            //记录用户购买记录
            accountLogsService.addAccountLog(accountLog);
            // 待匹配的购买
            fundingNotMatchedService.addFundingNotMatched(fnm);
        } catch (Exception e) {
            e.printStackTrace();
        }


        // 8.预期收益操作
        for (int i = 0; i < pDeadline; i++) {
            ExpectedReturn er = new ExpectedReturn();
            // 封装数据
            // 1. 用户id
            er.setUserId(userId);
            // 2. 产品id
            er.setProductId((product.getId()));
            // 3. 投资记录id
            er.setInvestRcord(pa.getpId());
            // 4. 收益日期 当前月份+1
            er.setExpectedDate(TimestampUtils.nextMonth(date.getYear(), date.getMonth(), i));
            // 5. 收益金额、-----从请求参数中获取
            er.setExpectedMoney(pMonthInterest);
            // 6. 创建日期 new Date()
            er.setCreateDate(date);
            expectedReturnService.addExpectedReturn(er);
        }
        // 9.发送短信，发送邮件
        logger.info("完成理财产品购买操作");
        // 10响应成功
        return true;

    }

    @RequestMapping(value = "/charges/ProductAccountBuying/{currentPage}",method = RequestMethod.GET)
    public Map<String,Object> productAccountBuying(@PathVariable int currentPage) {

//        PageHelper.startPage(需要显示的第几个页面，每个页面显示的数量);
//        下一行紧跟查询语句，不可以写其他的，否则没有效果。
        PageHelper.startPage(Integer.valueOf(currentPage),3);
        List<ProductAccount> all = productAccountService.findAll();
        //将查询到的数据封装到PageInfo对象
        PageInfo<ProductAccount> pageInfo=new PageInfo(all);
        Map<String,Object> m=new HashMap<>();
        m.put("data",pageInfo.getList());
        m.put("total",pageInfo.getTotal());

        return m;
    }


}
